package com.djz.tool.exception.handler;

import cn.hutool.extra.spring.SpringUtil;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.djz.tool.exception.base.BaseException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;
import java.util.Map;

/**
 * 交易异常统一处理
 * @author djz
 */
@ControllerAdvice
@RestControllerAdvice
public class GlobalExceptionResolver {

    @Autowired
    private Map<String, ExceptionHandler<BaseException>> exceptionHandlerMap;

    @org.springframework.web.bind.annotation.ExceptionHandler(value = Exception.class)
    @ResponseBody
    public Object resolveException(HttpServletRequest request,
                                   HttpServletResponse response,
                                   Object handler,
                                   Exception ex,
                                   WebRequest webRequest) {
        String name = StringUtils.firstToLowerCase(ex.getClass().getSimpleName());
        ExceptionHandler<BaseException> exceptionHandler = exceptionHandlerMap.get(name + "Handler");
        if (exceptionHandler == null) {
            exceptionHandler = SpringUtil.getBean(DefaultExceptionHandler.class);
        }

        // 处理异常并获取处理结果
        Object result = exceptionHandler.handleException(request, response, ex);

        // 判断请求类型决定返回视图还是JSON
        if (result != null) {
            // 返回JSON响应
            return result;
        } else {
            // 返回视图
            ModelAndView modelAndView = new ModelAndView();
            modelAndView.addObject("error", result);
            modelAndView.setViewName("error");
            return modelAndView;
        }
    }

    /**
     * 判断是否为AJAX请求
     */
    private boolean isAjaxRequest(HttpServletRequest request) {
        return "XMLHttpRequest".equals(request.getHeader("X-Requested-With"));
    }

    /**
     * 判断请求是否期望JSON响应
     */
    private boolean isContentTypeJson(HttpServletRequest request) {
        String accept = request.getHeader("Accept");
        return accept != null && accept.contains("application/json");
    }
}
